home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 23 / Amiga Format AFCD23 (Feb 1998, Issue 107).iso / -seriously_amiga- / shareware / programming / mui / mcc_monthnavigator / developer / c / examples / monthnavigator-demo.c
Text File  |  1997-12-06  |  35KB  |  1,012 lines

  1. /*
  2. **
  3. ** Copyright © 1996-1997 Kai Hofmann. All rights reserved.
  4. ** Demo for a registered MUI custom class!
  5. **
  6. ** $VER: MonthNavigator-Demo.c 16.5 (27.11.97)
  7. **
  8. */
  9.  
  10.  #define __MakeLib
  11.  
  12.  #include "system.h"
  13.  #include <mui/Date_mcc.h>
  14.  #include <libraries/mui.h>
  15.  #include <mui/MonthNavigator_mcc.h>
  16.  #include <proto/date.h>
  17.  #include <proto/muimaster.h>
  18.  #include <utility/tagitem.h>
  19.  #include <proto/utility.h>
  20.  #include <exec/libraries.h>
  21.  #include <exec/memory.h>
  22.  #include <proto/exec.h>
  23.  #include <proto/dos.h>
  24.  #include <proto/intuition.h>
  25.  #include <clib/alib_protos.h>
  26.  #include <string.h>
  27.  
  28.  
  29.  #ifdef DEBUG
  30.    void kprintf(UBYTE *fmt,...);
  31.    #define debug(x)    kprintf(x "\n");
  32.  #else
  33.    #define debug(x)
  34.  #endif
  35.  
  36.  
  37.  #ifndef MAKE_ID
  38.    #define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
  39.  #endif
  40.  
  41.  
  42.  struct MUI_CustomClass *App_CC=NULL,*Win_CC=NULL,*Str_CC=NULL,*MN_CC=NULL,*DateNavigator_CC=NULL;
  43.  
  44.  
  45.  struct Library *DateBase;
  46.  struct Library *MUIMasterBase;
  47.  static Object *App;
  48.  
  49.  
  50.  #define MUIA_Win_InputMode        ((TAG_USER | 494 << 16) | 0x8001)
  51.  #define MUIA_Win_DNObjectID        ((TAG_USER | 494 << 16) | 0x8002)
  52.  
  53.  #define MUIA_DateNavigator_ObjectID    ((TAG_USER | 494 << 16) | 0x8003)
  54.  #define MUIM_DateNavigator_Update    ((TAG_USER | 494 << 16) | 0x8004)
  55.  #define MUIM_DateNavigator_UpdateDay    ((TAG_USER | 494 << 16) | 0x8005)
  56.  #define MUIM_DateNavigator_MonthUpdate    ((TAG_USER | 494 << 16) | 0x8006)
  57.  
  58.  struct MUIP_DateNavigator_MonthUpdate    {ULONG MethodID; ULONG Month;};
  59.  
  60.  
  61.  struct DateNavigator_Data
  62.   {
  63.    Object *monthnavigator;
  64.    Object *month,*year,*day;
  65.   };
  66.  
  67.  
  68.  struct MN_Data
  69.   {
  70.    WORD  InputMode;
  71.   };
  72.  
  73.  
  74.  struct Calendar_Entry
  75.   {
  76.    UWORD  Day,Month;
  77.    LONG   Year;
  78.    STRPTR ShortHelp;
  79.   };
  80.  
  81.  
  82.  struct Calendar_List
  83.   {
  84.    struct Calendar_List  *Prev;
  85.    struct Calendar_List  *Next;
  86.    struct Calendar_Entry  Entry;
  87.   };
  88.  
  89.  
  90.  static APTR mempool = NULL;
  91.  static char *months[13];
  92.  static struct Calendar_List *root = NULL;
  93.  
  94.  /* ------------------------------------------------------------------------ */
  95.  
  96.  static ULONG STACKARGS DoSuperNew(struct IClass *cl, Object *obj, ULONG tags, ...)
  97.   {
  98.    return(DoSuperMethod(cl,obj,OM_NEW,&tags,NULL));
  99.   }
  100.  
  101.  /* --- Calendar list managment -------------------------------------------- */
  102.  
  103.  static struct Calendar_Entry *calendar_search(const UWORD Day, const UWORD Month, const LONG Year)
  104.   {
  105.    struct Calendar_List *p = root;
  106.  
  107.    while (p != NULL)
  108.     {
  109.      if ((Year == p->Entry.Year) && (Month == p->Entry.Month) && (Day == p->Entry.Day))
  110.       {
  111.        return(&(p->Entry));
  112.       }
  113.      p = p->Next;
  114.     }
  115.    return(NULL);
  116.   }
  117.  
  118.  
  119.  static struct Calendar_Entry *calendar_insert(const UWORD Day, const UWORD Month, const LONG Year, const STRPTR ShortHelp)
  120.   {
  121.    if ((ShortHelp != NULL) && (ShortHelp[0] != '\0'))
  122.     {
  123.      struct Calendar_List *l;
  124.  
  125.      l = (struct Calendar_List *)LibAllocPooled(mempool,sizeof(struct Calendar_List));
  126.      if (l != NULL)
  127.       {
  128.        l->Prev            = NULL;
  129.        l->Next            = NULL;
  130.        l->Entry.Day       = Day;
  131.        l->Entry.Month     = Month;
  132.        l->Entry.Year      = Year;
  133.        l->Entry.ShortHelp = (STRPTR)LibAllocPooled(mempool,(ULONG)strlen(ShortHelp)+1);
  134.        if (l->Entry.ShortHelp != NULL)
  135.         {
  136.          strcpy(l->Entry.ShortHelp,ShortHelp);
  137.          if (root == NULL)
  138.           {
  139.            root = l;
  140.           }
  141.          else
  142.           {
  143.            l->Next = root;
  144.            root->Prev = l;
  145.            root = l;
  146.           }
  147.          return(&(l->Entry));
  148.         }
  149.        else
  150.         {
  151.          LibFreePooled(mempool,l,sizeof(struct Calendar_List));
  152.         }
  153.       }
  154.     }
  155.    return(NULL);
  156.   }
  157.  
  158.  /* --- String class ------------------------------------------------------- */
  159.  
  160.  static ULONG Str_New(struct IClass *cl, Object *obj, struct opSet *msg)
  161.   {
  162.    /* subclass string gadget for MN drag&drop support */
  163.    obj = (Object *)DoSuperNew(cl,obj,
  164.                               MUIA_String_Format,    MUIV_String_Format_Left,
  165.                               MUIA_String_MaxLen,    30,
  166.                               MUIA_Frame,        MUIV_Frame_String,
  167.                               MUIA_Background,        MUII_TextBack,
  168.                               TAG_MORE,         msg->ops_AttrList
  169.                              );
  170.    return((ULONG)obj);
  171.   }
  172.  
  173.  
  174.  static ULONG Str_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragQuery *msg)
  175.   {
  176.    /*struct Str_Data *data = (struct Str_Data *)INST_DATA(cl,obj);*/
  177.    /*ULONG result;*/
  178.    ULONG Year,Month,Day;
  179.  
  180.    /* Test if the dropped object was an MN object */
  181.    if (get(msg->obj,MUIA_Date_Year,&Year) && get(msg->obj,MUIA_Date_Month,&Month) && get(msg->obj,MUIA_Date_Day,&Day))
  182.     {
  183.      if (Day > 0)
  184.       {
  185.        return(MUIV_DragQuery_Accept);
  186.       }
  187.     }
  188.    return(MUIV_DragQuery_Refuse);
  189.   }
  190.  
  191.  
  192.  static ULONG Str_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  193.   {
  194.    /*struct Str_Data *data = (struct Str_Data *)INST_DATA(cl,obj);*/
  195.    /*ULONG result;*/
  196.    char str[13];
  197.    ULONG Day,Month,Year;
  198.  
  199.    /* get date from MN object that was dropped onto the string gadget */
  200.    /*result =*/ get(msg->obj,MUIA_Date_Year,&Year);
  201.    /*result =*/ get(msg->obj,MUIA_Date_Month,&Month);
  202.    /*result =*/ get(msg->obj,MUIA_Date_Day,&Day);
  203.    /* Format as ISO8601 string and set */
  204.    date_FormatDate("%Y-%Dmv-%Ddv",(unsigned short)Day,(unsigned short)Month,(long)Year,date_Locale,str);
  205.    /*result =*/ set(obj,MUIA_String_Contents,(ULONG)str);
  206.    return(0);
  207.   }
  208.  
  209.  
  210.  static ULONG SAVEDS_ASM Str_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  211.   {
  212.    switch (msg->MethodID)
  213.     {
  214.      case OM_NEW            : return(Str_New(cl,obj,(struct opSet *)msg));
  215.      case MUIM_DragQuery        : return(Str_DragQuery(cl,obj,(struct MUIP_DragQuery *)msg));
  216.      case MUIM_DragDrop            : return(Str_DragDrop(cl,obj,(struct MUIP_DragDrop *)msg));
  217.      default                : return(DoSuperMethodA(cl,obj,msg));
  218.     }
  219.   }
  220.  
  221.  /* --- MonthNavigator class ----------------------------------------------- */
  222.  
  223.  static ULONG MN_Mark(struct IClass *cl, Object *obj, struct MUIP_MonthNavigator_Mark *msg)
  224.   {
  225.    /*ULONG result;*/
  226.    struct Calendar_Entry *e;
  227.  
  228.    /* Hook to mark Kai Hofmann's birthdays and display a bubble help */
  229.    if (e = calendar_search((UWORD)msg->Day,(UWORD)msg->Month,msg->Year))
  230.     {
  231.      /*result =*/ SetAttrs(msg->dayobj,
  232.                       MUIA_Text_PreParse,    "\033c\0338\033n",
  233.                       MUIA_ShortHelp,        e->ShortHelp,
  234.                     TAG_DONE
  235.               );
  236.     }
  237.    else if ((msg->Year >= 1970) && (msg->Month == 9) && (msg->Day == 18))
  238.     {
  239.      /*result =*/ SetAttrs(msg->dayobj,
  240.                       MUIA_Text_PreParse,    "\033c\0338\033n",
  241.                       MUIA_ShortHelp,        "Kai's birthday",
  242.                     TAG_DONE
  243.               );
  244.     }
  245.    else
  246.     {
  247.      struct DateStamp ds;
  248.      UWORD Day,Month;
  249.      LONG Year;
  250.  
  251.      DateStamp(&ds);
  252.      date_HeisDiffDate(1,1,1978,ds.ds_Days,&Day,&Month,&Year);
  253.      if ((Year == msg->Year) && (Month == msg->Month) && (Day == msg->Day))
  254.       {
  255.        /*result =*/ SetAttrs(msg->dayobj,
  256.                         MUIA_Text_PreParse,    "\033c\0338\033n",
  257.                         MUIA_ShortHelp,        "Today",
  258.                       TAG_DONE
  259.                 );
  260.       }
  261.     }
  262.    return(0);
  263.   }
  264.  
  265.  
  266.  static ULONG MN_DragQuery(struct IClass *cl, Object *obj, struct MUIP_MonthNavigator_DragQuery *msg)
  267.   {
  268.    struct MN_Data *data = (struct MN_Data *)INST_DATA(cl,obj);
  269.  
  270.    if (data->InputMode != MUIV_MonthNavigator_InputMode_None)
  271.     {
  272.      if (calendar_search((UWORD)msg->Day,(UWORD)msg->Month,msg->Year) == NULL)
  273.       {
  274.        /*ULONG result;*/
  275.        ULONG Year,Month,Day;
  276.        STRPTR str;
  277.  
  278.        /* Test if the dragged object is of a specified type */
  279.        if (get(msg->obj,MUIA_Date_Year,&Year) && get(msg->obj,MUIA_Date_Month,&Month) && get(msg->obj,MUIA_Date_Day,&Day))
  280.         {
  281.          if (date_ValidHeisDate((unsigned short)Day,(unsigned short)Month,(long)Year))
  282.           {
  283.            return(MUIV_DragQuery_Accept);
  284.           }
  285.         }
  286.        else if (get(obj,MUIA_Text_Contents,&str) || get(obj,MUIA_String_Contents,&str))
  287.         {
  288.          long year,ayear;
  289.          unsigned short day,month,aday,amonth;
  290.          struct DateStamp ds;
  291.  
  292.          DateStamp(&ds);
  293.          date_HeisDiffDate(1,1,1978,ds.ds_Days,&aday,&amonth,&ayear);
  294.          if (date_ParseDate(NULL,str,date_Locale,date_Heis,aday,amonth,ayear,&day,&month,&year,NULL) == 0)
  295.           {
  296.            return(MUIV_DragQuery_Accept);
  297.           }
  298.         }
  299.       }
  300.     }
  301.    return(MUIV_DragQuery_Refuse);
  302.   }
  303.  
  304.  
  305.  static ULONG MN_DragDrop(struct IClass *cl, Object *obj, struct MUIP_MonthNavigator_DragDrop *msg)
  306.   {
  307.    /*ULONG result;*/
  308.    ULONG Day,Month,Year;
  309.  
  310.    /* Drag&Drop method that allows to drop a date object onto a day button
  311.       (will be highlighted and shown via bubble help)
  312.    */
  313.    if (!(get(msg->obj,MUIA_Date_Year,&Year) && get(msg->obj,MUIA_Date_Month,&Month) && get(msg->obj,MUIA_Date_Day,&Day)))
  314.     {
  315.      STRPTR str;
  316.  
  317.      if (get(msg->obj,MUIA_Text_Contents,&str) || get(msg->obj,MUIA_String_Contents,&str))
  318.       {
  319.        long year,ayear;
  320.        unsigned short day,month,aday,amonth;
  321.        struct DateStamp ds;
  322.  
  323.        DateStamp(&ds);
  324.        date_HeisDiffDate(1,1,1978,ds.ds_Days,&aday,&amonth,&ayear);
  325.        if (date_ParseDate(NULL,str,date_Locale,date_Heis,aday,amonth,ayear,&day,&month,&year,NULL) != 0)
  326.         {
  327.          return(FALSE);
  328.         }
  329.        Year = (ULONG)year;
  330.        Month = (ULONG)month;
  331.        Day = (ULONG)day;
  332.       }
  333.      else
  334.       {
  335.        return(FALSE);
  336.       }
  337.     }
  338.    if (date_ValidHeisDate((unsigned short)Day,(unsigned short)Month,(long)Year))
  339.     {
  340.      struct Calendar_Entry *e;
  341.      static char date[13];
  342.  
  343.      date_FormatDate("%Y-%Dmf-%Ddf",(unsigned short)Day,(unsigned short)Month,(long)Year,date_Locale,date);
  344.      e = calendar_insert((UWORD)msg->Day,(UWORD)msg->Month,msg->Year,date);
  345.      if (e != NULL)
  346.       {
  347.        /*result =*/ SetAttrs(msg->dayobj,
  348.                         MUIA_Text_PreParse,    "\033c\0338\033n",
  349.                         MUIA_ShortHelp,        e->ShortHelp,
  350.                       TAG_DONE
  351.                 );
  352.        return(TRUE);
  353.       }
  354.     }
  355.    return(FALSE);
  356.   }
  357.  
  358.  
  359.  static ULONG MN_New(struct IClass *cl, Object *obj, struct opSet *msg)
  360.   {
  361.    obj = (Object *)DoSuperNew(cl,obj,
  362.                               TAG_MORE,         msg->ops_AttrList
  363.                              );
  364.    if (obj != NULL)
  365.     {
  366.      struct MN_Data *data = (struct MN_Data *)INST_DATA(cl,obj);
  367.      struct TagItem *tags,*tag;
  368.  
  369.      tags = msg->ops_AttrList;
  370.      while (tag = NextTagItem(&tags))
  371.       {
  372.        switch (tag->ti_Tag)
  373.         {
  374.          case MUIA_MonthNavigator_InputMode    : data->InputMode = (UWORD)tag->ti_Data;
  375.                                                 break;
  376.         }
  377.       }
  378.     }
  379.    return((ULONG)obj);
  380.   }
  381.  
  382.  
  383.  static ULONG SAVEDS_ASM MN_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  384.   {
  385.    switch (msg->MethodID)
  386.     {
  387.      case OM_NEW            : return(MN_New(cl,obj,(struct opSet *)msg));
  388.      case MUIM_MonthNavigator_Mark    : return(MN_Mark(cl,obj,(struct MUIP_MonthNavigator_Mark *)msg));
  389.      case MUIM_MonthNavigator_DragQuery    : return(MN_DragQuery(cl,obj,(struct MUIP_MonthNavigator_DragQuery *)msg));
  390.      case MUIM_MonthNavigator_DragDrop    : return(MN_DragDrop(cl,obj,(struct MUIP_MonthNavigator_DragDrop *)msg));
  391.      default                : return(DoSuperMethodA(cl,obj,msg));
  392.     }
  393.   }
  394.  
  395.  /* --- DateNavigator class ------------------------------------------------ */
  396.  
  397.  static ULONG DateNavigator_Update(struct IClass *cl, Object *obj, Msg msg)
  398.   {
  399.    struct DateNavigator_Data *data = (struct DateNavigator_Data *)INST_DATA(cl,obj);
  400.    ULONG year,month;
  401.  
  402.    /* Update the Monthnavigator with the new month/year values */
  403.    get(data->month,MUIA_Cycle_Active,&month);
  404.    month++;
  405.    get(data->year,MUIA_Numeric_Value,&year);
  406.    SetAttrs(data->monthnavigator,
  407.               MUIA_Date_Month,    month,
  408.               MUIA_Date_Year,    year,
  409.             TAG_DONE
  410.            );
  411.    /* set day to 0, because the user has not selected something within the new month/year */
  412.    if (data->day != NULL)
  413.     {
  414.      set(data->day,MUIA_Text_Contents,"0");
  415.     }
  416.    return(0);
  417.   }
  418.  
  419.  
  420.  static ULONG DateNavigator_UpdateDay(struct IClass *cl, Object *obj, Msg msg)
  421.   {
  422.    struct DateNavigator_Data *data = (struct DateNavigator_Data *)INST_DATA(cl,obj);
  423.    ULONG day;
  424.    char daystr[5];
  425.  
  426.    /* Update the text day object with MonthNavigators actual day */
  427.    get(data->monthnavigator,MUIA_Date_Day,&day);
  428.    date_FormatDate("%Ddv",(unsigned short)day,0,0,date_Locale,daystr);
  429.    set(data->day,MUIA_Text_Contents,daystr);
  430.    return(0);
  431.   }
  432.  
  433.  
  434.  static ULONG DateNavigator_MonthUpdate(struct IClass *cl, Object *obj, struct MUIP_DateNavigator_MonthUpdate *msg)
  435.   {
  436.    struct DateNavigator_Data *data = (struct DateNavigator_Data *)INST_DATA(cl,obj);
  437.    /*ULONG result;*/
  438.  
  439.    /* Update the month cycle gadget with MonthNavigators actual month */
  440.    /*result =*/ DoMethod(data->month,MUIM_NoNotifySet,MUIA_Cycle_Active,msg->Month-1);
  441.    return(0);
  442.   }
  443.  
  444.  
  445.  static ULONG DateNavigator_New(struct IClass *cl, Object *obj, struct opSet *msg)
  446.   {
  447.    struct TagItem *tags,*tag;
  448.    ULONG inputmode,objectid=0;
  449.    Object *monthnavigator,*monthobj,*yearobj,*pyearobj,*myearobj,
  450.       *dayobj = NULL;
  451.  
  452.    inputmode = MUIV_MonthNavigator_InputMode_None;
  453.    /* Read new message attributes */
  454.    tags = msg->ops_AttrList;
  455.    while (tag = NextTagItem(&tags))
  456.     {
  457.      switch (tag->ti_Tag)
  458.       {
  459.        case MUIA_MonthNavigator_InputMode    : inputmode = (ULONG)tag->ti_Data;
  460.                                               break;
  461.        case MUIA_DateNavigator_ObjectID     : objectid = (ULONG)tag->ti_Data;
  462.                                                   break;
  463.       }
  464.     }
  465.    /* Create DateNavigator object */
  466.    obj = (Object *)DoSuperNew(cl,obj,
  467.                               MUIA_Group_Horiz,         FALSE,
  468.                               MUIA_Group_SameWidth,        TRUE,
  469.                               MUIA_Background,            MUII_GroupBack,
  470.                               MUIA_Group_Child,            HGroup,
  471.                                 MUIA_Frame,            MUIV_Frame_Group,
  472.                                 MUIA_Background,        MUII_GroupBack,
  473.                                 MUIA_Group_SameHeight,        TRUE,
  474.                                 MUIA_Group_Child,        RectangleObject,
  475.                                   MUIA_HorizWeight,        (inputmode == MUIV_MonthNavigator_InputMode_RelVerify) ? 100 : 50,
  476.                                 End,
  477.                                 MUIA_Group_Child,        (inputmode == MUIV_MonthNavigator_InputMode_RelVerify) ? dayobj = TextObject,
  478.                                   MUIA_Text_PreParse,        "\33r",
  479.                                   MUIA_Frame,            MUIV_Frame_Text,
  480.                                   MUIA_Background,        MUII_TextBack,
  481.                                   MUIA_FixWidthTxt,        "MM",
  482.                                 End :
  483.                                 RectangleObject,
  484.                                   MUIA_HorizWeight,        50,
  485.                                 End,
  486.                                 MUIA_Group_Child,        monthobj = CycleObject,
  487.                                   MUIA_Cycle_Entries,        months,
  488.                                   MUIA_Font,            MUIV_Font_Button,
  489.                                   MUIA_CycleChain,        1,
  490.                                 End,
  491.                                 MUIA_Group_Child,        yearobj = NumericbuttonObject,
  492.                                   MUIA_Numeric_Format,        "%lu",
  493.                                   MUIA_Numeric_Min,        8,
  494.                                   MUIA_Numeric_Max,        8000,
  495.                                   MUIA_Font,            MUIV_Font_Button,
  496.                                   MUIA_CycleChain,        1,
  497.                                 End,
  498.                                 MUIA_Group_Child,        myearobj = ImageObject,
  499.                                   MUIA_Frame,               MUIV_Frame_Button,
  500.                                   MUIA_InputMode,           MUIV_InputMode_RelVerify,
  501.                                   MUIA_Image_Spec,          MUII_ArrowLeft,
  502.                                   MUIA_Image_FreeVert,      TRUE,
  503.                                   MUIA_Background,          MUII_ButtonBack,
  504.                                   MUIA_ShowSelState,        FALSE,
  505.                                   MUIA_CycleChain,        1,
  506.                                 End,
  507.                                 MUIA_Group_Child,        pyearobj = ImageObject,
  508.                                   MUIA_Frame,               MUIV_Frame_Button,
  509.                                   MUIA_InputMode,           MUIV_InputMode_RelVerify,
  510.                                   MUIA_Image_Spec,          MUII_ArrowRight,
  511.                                   MUIA_Image_FreeVert,      TRUE,
  512.                                   MUIA_Background,          MUII_ButtonBack,
  513.                                   MUIA_ShowSelState,        FALSE,
  514.                                   MUIA_CycleChain,        1,
  515.                                 End,
  516.                                 MUIA_Group_Child,        RectangleObject,
  517.                                 End,
  518.                               End,
  519.                               MUIA_Group_Child,            monthnavigator = NewObject(MN_CC->mcc_Class,NULL,
  520.                                 MUIA_Frame,            MUIV_Frame_Group,
  521.                                 MUIA_FrameTitle,        "MonthNavigator.mcc",
  522.                                 MUIA_Background,        MUII_GroupBack,
  523.                                 MUIA_MonthNavigator_InputMode,    inputmode,
  524.                                 MUIA_MonthNavigator_Draggable,    TRUE,
  525.                                 MUIA_ObjectID,            objectid,
  526.                                 MUIA_Dropable,                inputmode == MUIV_MonthNavigator_InputMode_None ? FALSE : TRUE,
  527.                                 MUIA_MonthNavigator_Dropable,        inputmode == MUIV_MonthNavigator_InputMode_None ? FALSE : TRUE,
  528.                                 MUIA_CycleChain,        1,
  529.                                 /*MUIA_Font,            MUIV_Font_Tiny,*/
  530.                               End,
  531.                               MUIA_Group_Child,            RectangleObject,
  532.                               End,
  533.                               TAG_MORE,             msg->ops_AttrList
  534.                              );
  535.    if (obj != NULL)
  536.     {
  537.      struct DateNavigator_Data *data = (struct DateNavigator_Data *)INST_DATA(cl,obj);
  538.      ULONG month,year,day;
  539.      char daystr[5];
  540.      /*ULONG result;*/
  541.  
  542.      /* Save pointers to sub-objects for later usage */
  543.      data->monthnavigator = monthnavigator;
  544.      data->month = monthobj;
  545.      data->year = yearobj;
  546.      data->day = dayobj;
  547.  
  548.      /* Init month/year/day with MonthNavigator values */
  549.      /*result =*/ DoMethod(monthnavigator,MUIM_Date_SetCurrent);
  550.      get(monthnavigator,MUIA_Date_Month,&month);
  551.      set(monthobj,MUIA_Cycle_Active,month-1);
  552.      get(monthnavigator,MUIA_Date_Year,&year);
  553.      set(yearobj,MUIA_Numeric_Default,year);
  554.      set(yearobj,MUIA_Numeric_Value,year);
  555.      if (dayobj != NULL)
  556.       {
  557.        get(monthnavigator,MUIA_Date_Day,&day);
  558.        date_FormatDate("%Ddv",(unsigned short)day,0,0,date_Locale,daystr);
  559.        set(dayobj,MUIA_Text_Contents,daystr);
  560.        /*result =*/ DoMethod(monthnavigator,MUIM_Notify,MUIA_Date_Day,MUIV_EveryTime,obj,1,MUIM_DateNavigator_UpdateDay);
  561.       }
  562.      /* Set notifies for interaction */
  563.      /*result =*/ DoMethod(monthobj,MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,obj,1,MUIM_DateNavigator_Update);
  564.      /*result =*/ DoMethod(yearobj,MUIM_Notify,MUIA_Numeric_Value,MUIV_EveryTime,obj,1,MUIM_DateNavigator_Update);
  565.      /*result =*/ DoMethod(myearobj,MUIM_Notify,MUIA_Pressed,FALSE,yearobj,2,MUIM_Numeric_Decrease,1);
  566.      /*result =*/ DoMethod(pyearobj,MUIM_Notify,MUIA_Pressed,FALSE,yearobj,2,MUIM_Numeric_Increase,1);
  567.      /*result =*/ DoMethod(monthnavigator,MUIM_Notify,MUIA_Date_Year,MUIV_EveryTime,yearobj,3,MUIM_NoNotifySet,MUIA_Numeric_Value,MUIV_TriggerValue);
  568.      /*result =*/ DoMethod(monthnavigator,MUIM_Notify,MUIA_Date_Month,MUIV_EveryTime,obj,2,MUIM_DateNavigator_MonthUpdate,MUIV_TriggerValue);
  569.     }
  570.    return((ULONG)obj);
  571.   }
  572.  
  573.  
  574.  static ULONG SAVEDS_ASM DateNavigator_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  575.   {
  576.    switch (msg->MethodID)
  577.     {
  578.      case OM_NEW                : return(DateNavigator_New(cl,obj,(struct opSet *)msg));
  579.      case MUIM_DateNavigator_Update        : return(DateNavigator_Update(cl,obj,msg));
  580.      case MUIM_DateNavigator_UpdateDay        : return(DateNavigator_UpdateDay(cl,obj,msg));
  581.      case MUIM_DateNavigator_MonthUpdate    : return(DateNavigator_MonthUpdate(cl,obj,(struct MUIP_DateNavigator_MonthUpdate *)msg));
  582.      default                    : return(DoSuperMethodA(cl,obj,msg));
  583.     }
  584.   }
  585.  
  586.  /* --- Window class ------------------------------------------------------- */
  587.  
  588.  static ULONG Win_New(struct IClass *cl, Object *obj, struct opSet *msg)
  589.   {
  590.    struct TagItem *tags,*tag;
  591.    ULONG type = MUIV_MonthNavigator_InputMode_None,objectid=0;
  592.    Object *saveobj,*loadobj;
  593.  
  594.    /* Read new message attributes */
  595.    tags = msg->ops_AttrList;
  596.    while (tag = NextTagItem(&tags))
  597.     {
  598.      switch (tag->ti_Tag)
  599.       {
  600.        case MUIA_Win_InputMode    : type = (ULONG)tag->ti_Data;
  601.                                   break;
  602.        case MUIA_Win_DNObjectID : objectid = (ULONG)tag->ti_Data;
  603.                                   break;
  604.       }
  605.     }
  606.    /* create window object */
  607.    obj = (Object *)DoSuperNew(cl,obj,
  608.                               MUIA_Window_ID,            MAKE_ID('D','E','M','0'+type),
  609.                               MUIA_Window_Title,        (type == MUIV_MonthNavigator_InputMode_None) ? "ReadOnly" : ((type == MUIV_MonthNavigator_InputMode_RelVerify) ? "RelVerify" : "Immediate"),
  610.                               MUIA_Window_ScreenTitle,        "MonthNavigator-Demo V16.5",
  611.                               MUIA_Window_RootObject,        VGroup,
  612.                                 MUIA_Group_SameWidth,        TRUE,
  613.                                 MUIA_Background,        MUII_GroupBack,
  614.                                 MUIA_Group_Child,        NewObject(DateNavigator_CC->mcc_Class,NULL,
  615.                                         MUIA_MonthNavigator_InputMode,    type,
  616.                                         MUIA_DateNavigator_ObjectID,    objectid,
  617.                                       TAG_DONE
  618.                                          ),
  619.                                 MUIA_Group_Child,        HGroup,
  620.                                   MUIA_Frame,            MUIV_Frame_Group,
  621.                                   MUIA_Background,        MUII_GroupBack,
  622.                                   MUIA_Group_SameHeight,    TRUE,
  623.                                   MUIA_Group_Child,        Label2("Drop here:"),
  624.                                   MUIA_Group_Child,        NewObject(Str_CC->mcc_Class,NULL,
  625.                     MUIA_Dropable,        TRUE,
  626.                     MUIA_Draggable,        TRUE,
  627.                   TAG_DONE),
  628.                                 End,
  629.                                 MUIA_Group_Child,        HGroup,
  630.                                   MUIA_Frame,            MUIV_Frame_Group,
  631.                                   MUIA_Background,        MUII_GroupBack,
  632.                                   MUIA_Group_SameHeight,    TRUE,
  633.                                   MUIA_Group_Child,        loadobj = TextObject,
  634.                                     MUIA_Frame,            MUIV_Frame_Button,
  635.                                     MUIA_Background,        MUII_ButtonBack,
  636.                                     MUIA_Font,            MUIV_Font_Button,
  637.                                     MUIA_Text_PreParse,        "\33c",
  638.                                     MUIA_InputMode,        MUIV_InputMode_RelVerify,
  639.                                     MUIA_Text_Contents,        "Load",
  640.                                     MUIA_Text_HiChar,        'L',
  641.                                     MUIA_ControlChar,        'l',
  642.                                     MUIA_CycleChain,        1,
  643.                                   End,
  644.                                   MUIA_Group_Child,        saveobj = TextObject,
  645.                                     MUIA_Frame,            MUIV_Frame_Button,
  646.                                     MUIA_Background,        MUII_ButtonBack,
  647.                                     MUIA_Font,            MUIV_Font_Button,
  648.                                     MUIA_Text_PreParse,        "\33c",
  649.                                     MUIA_InputMode,        MUIV_InputMode_RelVerify,
  650.                                     MUIA_Text_Contents,        "Save",
  651.                                     MUIA_Text_HiChar,        'S',
  652.                                     MUIA_ControlChar,        's',
  653.                                     MUIA_CycleChain,        1,
  654.                                   End,
  655.                                 End,
  656.                               End,
  657.                               TAG_MORE, msg->ops_AttrList
  658.                              );
  659.    if (obj != NULL)
  660.     {
  661.      /*ULONG result;*/
  662.  
  663.      /* Set notify for application load/save buttons */
  664.      /*result =*/ DoMethod(loadobj,MUIM_Notify,MUIA_Pressed,FALSE,MUIV_Notify_Application,2,MUIM_Application_Load,MUIV_Application_Load_ENV);
  665.      /*result =*/ DoMethod(saveobj,MUIM_Notify,MUIA_Pressed,FALSE,MUIV_Notify_Application,2,MUIM_Application_Save,MUIV_Application_Save_ENV);
  666.     }
  667.    return((ULONG)obj);
  668.   }
  669.  
  670.  
  671.  static ULONG SAVEDS_ASM Win_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  672.   {
  673.    switch (msg->MethodID)
  674.     {
  675.      case OM_NEW            : return(Win_New(cl,obj,(struct opSet *)msg));
  676.      default                : return(DoSuperMethodA(cl,obj,msg));
  677.     }
  678.   }
  679.  
  680.  /* --- Application class -------------------------------------------------- */
  681.  
  682.  static ULONG App_New(struct IClass *cl, Object *obj, struct opSet *msg)
  683.   {
  684.    Object *win1,*win2,*win3;
  685.  
  686.    /* Create application object with three different windows and open windows */
  687.    obj = (Object *)DoSuperNew(cl,obj,
  688.                               MUIA_Application_Title,           "MonthNavigator-Demo",
  689.                               MUIA_Application_Author,          "Kai Hofmann",
  690.                               MUIA_Application_Copyright,       "© 1996-1997 Kai Hofmann",
  691.                               MUIA_Application_Version,         "$VER: MonthNavigator-Demo 16.5 " __AMIGADATE__,
  692.                               MUIA_Application_Description,     "MonthNavigator demonstration program",
  693.                               MUIA_Application_Base,            "MNDEMO",
  694.                               MUIA_Application_SingleTask,      TRUE,
  695.                               MUIA_Application_Active,          TRUE,
  696.                               MUIA_Application_Window,        win1 = NewObject(Win_CC->mcc_Class,NULL,
  697.                                            MUIA_Win_InputMode,    MUIV_MonthNavigator_InputMode_None,
  698.                                            MUIA_Win_DNObjectID,    1,
  699.                                          TAG_DONE
  700.                                         ),
  701.                               MUIA_Application_Window,        win2 = NewObject(Win_CC->mcc_Class,NULL,
  702.                                            MUIA_Win_InputMode,    MUIV_MonthNavigator_InputMode_RelVerify,
  703.                                            MUIA_Win_DNObjectID,    2,
  704.                                          TAG_DONE
  705.                                         ),
  706.                               MUIA_Application_Window,        win3 = NewObject(Win_CC->mcc_Class,NULL,
  707.                                            MUIA_Win_InputMode,    MUIV_MonthNavigator_InputMode_Immediate,
  708.                                            MUIA_Win_DNObjectID,    3,
  709.                                          TAG_DONE
  710.                                         ),
  711.                               TAG_MORE, msg->ops_AttrList
  712.                              );
  713.    if (obj != NULL)
  714.     {
  715.      /*struct App_Data *data = (struct App_Data *)INST_DATA(cl,obj);*/
  716.      /*ULONG result;*/
  717.  
  718.      /*result =*/ DoMethod(win1,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,MUIV_Notify_Application,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  719.      set(win1,MUIA_Window_Open,TRUE);
  720.      /*result =*/ DoMethod(win2,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,MUIV_Notify_Application,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  721.      set(win2,MUIA_Window_Open,TRUE);
  722.      /*result =*/ DoMethod(win3,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,MUIV_Notify_Application,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  723.      set(win3,MUIA_Window_Open,TRUE);
  724.     }
  725.    return((ULONG)obj);
  726.   }
  727.  
  728.  
  729.  static ULONG SAVEDS_ASM App_Dispatcher(REG(A0) struct IClass *cl, REG(A2) Object *obj, REG(A1) Msg msg)
  730.   {
  731.    switch (msg->MethodID)
  732.     {
  733.      case OM_NEW            : return(App_New(cl,obj,(struct opSet *)msg));
  734.      default                : return(DoSuperMethodA(cl,obj,msg));
  735.     }
  736.   }
  737.  
  738.  /* --- Simple error requester --------------------------------------------- */
  739.  
  740.  static void OpenReq(char *const str)
  741.   {
  742.    struct EasyStruct req =
  743.     {
  744.      sizeof(struct EasyStruct),
  745.      0,
  746.      "MonthNavigator-Demo",
  747.      NULL,
  748.      "OK",
  749.     };
  750.  
  751.    req.es_TextFormat = str;
  752.    EasyRequest(NULL,&req,NULL,(ULONG)MUIMASTER_VMIN);
  753.   }
  754.  
  755.  /* --- Initialization/Cleanup of privat custom classes -------------------- */
  756.  
  757.  long muiclasses_Init(void)
  758.   {
  759.    long retstat = RETURN_OK;
  760.  
  761.    /* create privat custom classes: Application, Window, String, DateNavigator */
  762.    App_CC = MUI_CreateCustomClass(NULL,MUIC_Application,NULL,0,App_Dispatcher);
  763.    if (App_CC == NULL)
  764.     {
  765.      OpenReq("Can not create 'App' privat custom class!");
  766.      retstat = RETURN_ERROR;
  767.     }
  768.    else
  769.     {
  770.      Win_CC = MUI_CreateCustomClass(NULL,MUIC_Window,NULL,0,Win_Dispatcher);
  771.      if (Win_CC == NULL)
  772.       {
  773.        OpenReq("Can not create 'Win' privat custom class!");
  774.        retstat = RETURN_ERROR;
  775.       }
  776.      else
  777.       {
  778.        Str_CC = MUI_CreateCustomClass(NULL,MUIC_String,NULL,0,Str_Dispatcher);
  779.        if (Str_CC == NULL)
  780.         {
  781.          OpenReq("Can not create 'Str' privat custom class!");
  782.          retstat = RETURN_ERROR;
  783.         }
  784.        else
  785.         {
  786.          MN_CC = MUI_CreateCustomClass(NULL,MUIC_MonthNavigator,NULL,sizeof(struct MN_Data),MN_Dispatcher);
  787.          if (MN_CC == NULL)
  788.           {
  789.            OpenReq("Can not create 'MN' privat custom class!");
  790.            retstat = RETURN_ERROR;
  791.           }
  792.          else
  793.           {
  794.            DateNavigator_CC = MUI_CreateCustomClass(NULL,MUIC_Group,NULL,sizeof(struct DateNavigator_Data),DateNavigator_Dispatcher);
  795.            if (DateNavigator_CC == NULL)
  796.             {
  797.              OpenReq("Can not create 'DateNavigator' privat custom class!");
  798.              retstat = RETURN_ERROR;
  799.             }
  800.           }
  801.         }
  802.       }
  803.     }
  804.    return(retstat);
  805.   }
  806.  
  807.  
  808.  long muiclasses_Cleanup(void)
  809.   {
  810.    long retstat = RETURN_OK;
  811.  
  812.    if (DateNavigator_CC != NULL)
  813.     {
  814.      if (!MUI_DeleteCustomClass(DateNavigator_CC))
  815.       {
  816.        OpenReq("Can not delete 'DateNavigator' privat custom class!");
  817.        retstat = RETURN_ERROR;
  818.       }
  819.     }
  820.    if (MN_CC != NULL)
  821.     {
  822.      if (!MUI_DeleteCustomClass(MN_CC))
  823.       {
  824.        OpenReq("Can not delete 'MN' privat custom class!");
  825.        retstat = RETURN_ERROR;
  826.       }
  827.     }
  828.    if (Str_CC != NULL)
  829.     {
  830.      if (!MUI_DeleteCustomClass(Str_CC))
  831.       {
  832.        OpenReq("Can not delete 'Str' privat custom class!");
  833.        retstat = RETURN_ERROR;
  834.       }
  835.     }
  836.    if (Win_CC != NULL)
  837.     {
  838.      if (!MUI_DeleteCustomClass(Win_CC))
  839.       {
  840.        OpenReq("Can not delete 'Win' privat custom class!");
  841.        retstat = RETURN_ERROR;
  842.       }
  843.     }
  844.    if (App_CC != NULL)
  845.     {
  846.      if (!MUI_DeleteCustomClass(App_CC))
  847.       {
  848.        OpenReq("Can not delete 'App' privat custom class!");
  849.        retstat = RETURN_ERROR;
  850.       }
  851.     }
  852.    return(retstat);
  853.   }
  854.  
  855.  /* --- Initialization/Cleanup and main GUI loop --------------------------- */
  856.  
  857.  long gui_Init(void)
  858.   {
  859.    long retstat;
  860.  
  861.    MUIMasterBase = OpenLibrary((UBYTE *)MUIMASTER_NAME,(unsigned long)MUIMASTER_VMIN);
  862.    if (MUIMasterBase != NULL)
  863.     {
  864.      retstat = muiclasses_Init();
  865.      if (retstat == RETURN_OK)
  866.       {
  867.        Object *mn;
  868.  
  869.        /* test if MonthNavigator custom class is installed */
  870.        mn = MUI_NewObject(MUIC_MonthNavigator,
  871.                           TAG_DONE
  872.                          );
  873.        if (mn != NULL)
  874.         {
  875.          MUI_DisposeObject(mn);
  876.          /* create private application object */
  877.          App = NewObject(App_CC->mcc_Class,NULL,TAG_DONE);
  878.          if (App == NULL)
  879.           {
  880.            /*retstat =*/ muiclasses_Cleanup();
  881.            CloseLibrary(MUIMasterBase);
  882.            OpenReq("Can not create application object!");
  883.            retstat = RETURN_FAIL;
  884.           }
  885.         }
  886.        else
  887.         {
  888.          /*retstat =*/ muiclasses_Cleanup();
  889.          CloseLibrary(MUIMasterBase);
  890.          OpenReq("Missing MonthNavigator.mcc!");
  891.          retstat = RETURN_FAIL;
  892.         }
  893.       }
  894.      else
  895.       {
  896.        /*retstat =*/ muiclasses_Cleanup();
  897.        CloseLibrary(MUIMasterBase);
  898.       }
  899.     }
  900.    else
  901.     {
  902.      OpenReq("Can not open muimaster.library V%lu!");
  903.      retstat = RETURN_FAIL;
  904.     }
  905.    return(retstat);
  906.   }
  907.  
  908.  
  909.  long gui_Cleanup(void)
  910.   {
  911.    long retstat = RETURN_OK;
  912.  
  913.    if (MUIMasterBase != NULL)
  914.     {
  915.      if (App != NULL)
  916.       {
  917.        MUI_DisposeObject(App);
  918.       }
  919.      retstat = muiclasses_Cleanup();
  920.      if (retstat == RETURN_OK)
  921.       {
  922.        CloseLibrary(MUIMasterBase);
  923.       }
  924.      else
  925.       {
  926.        OpenReq("Can not close muimaster.library!");
  927.        retstat = RETURN_FAIL;
  928.       }
  929.     }
  930.    return(retstat);
  931.   }
  932.  
  933.  
  934.  void gui_MainLoop(void)
  935.   {
  936.    if (App != NULL) /* Optimized MUI main loop runs until application quit recived */
  937.     {
  938.      ULONG signals=0;
  939.  
  940.      while (DoMethod(App,(unsigned long)MUIM_Application_NewInput,&signals) != MUIV_Application_ReturnID_Quit)
  941.       {
  942.        if (signals)
  943.         {
  944.          signals = Wait(signals | SIGBREAKF_CTRL_C); /* CTRL-C test */
  945.          if (signals & SIGBREAKF_CTRL_C)
  946.           {
  947.            /*ULONG result;*/
  948.  
  949.            /* send application quit method for shutdown */
  950.            /*result =*/ DoMethod(App,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  951.           }
  952.         }
  953.       }
  954.     }
  955.   }
  956.  
  957.  /* ------------------------------------------------------------------------ */
  958.  
  959.  void main(void)
  960.   {
  961.    BOOL error = FALSE;
  962.  
  963.    DateBase = OpenLibrary(DATE_NAME,33); /* Open date.library minimum 33.286 */
  964.    if (DateBase != NULL)
  965.     {
  966.      if (((DateBase->lib_Version > 33)) || ((DateBase->lib_Version == 33) && (DateBase->lib_Revision >= 286)))
  967.       {
  968.        short i;
  969.        char mn[15];
  970.  
  971.        mempool = LibCreatePool(MEMF_PUBLIC,24*(12+10*2),24);
  972.        if (mempool != NULL)
  973.         {
  974.          for (i=0;i<12;i++) /* Get the month names from date.library for the local language */
  975.           {
  976.            date_MonthText(i+1,mn,date_Locale);
  977.            months[i] = (char *)LibAllocPooled(mempool,(ULONG)strlen(mn)+1);
  978.            if (months[i] != NULL)
  979.             {
  980.              strcpy(months[i],mn);
  981.             }
  982.            else /* error -> cleanup */
  983.             {
  984.              OpenReq("Out of memory error!");
  985.              error = TRUE;
  986.              break;
  987.             }
  988.           }
  989.          if (!error)
  990.           {
  991.            months[12] = NULL;
  992.            if (gui_Init() == RETURN_OK) /* Init GUI */
  993.             {
  994.              gui_MainLoop(); /* GUI main loop */
  995.              /*retstat =*/ gui_Cleanup(); /* Cleanup GUI */
  996.             }
  997.           }
  998.          LibDeletePool(mempool);
  999.         }
  1000.       }
  1001.      else
  1002.       {
  1003.        OpenReq("Can not open date.library V33.286");
  1004.       }
  1005.      CloseLibrary(DateBase);
  1006.     }
  1007.    else
  1008.     {
  1009.      OpenReq("Can not open date.library V33");
  1010.     }
  1011.   }
  1012.